#include "snake5.h"
#include "ui_snake5.h"
#include "dialog_1.h"
#include <QPainter>
#include<QTimer>
#include<QKeyEvent>

Snake5::Snake5(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Snake5),Run(false),speed(250),nScore(0),Change(false),Shorten(false)
          {
              ui->setupUi(this);
              this->setGeometry(QRect(600,300,500,600));//窗体矩形框
          }

Snake5::~Snake5()
{
    delete ui;
}

//画图
void Snake5::paintEvent(QPaintEvent *event){//调用函数
    QPainter painter(this);
    if(Change){
        initBoom();
        Change=false;
    }
    if(!Run){
        initSnake();
        initBoom();
    }


    //外框
    painter.setPen(Qt::black);
    painter.setBrush(Qt::gray);
    painter.drawRect(30,30,440,540);
    //内框
    painter.setPen(Qt::black);
    painter.setBrush(Qt::black);
    painter.drawRect(40,40,420,520);

    //画蛇
    if(nScore<=10){
    painter.setPen(Qt::black);
    painter.setBrush(Qt::red);
    painter.drawRects(&vSnakeRect[0],vSnakeRect.size());
    }
    else if(nScore>10&&nScore<=30){
        painter.setPen(Qt::black);
        painter.setBrush(Qt::yellow);
        painter.drawRects(&vSnakeRect[0],vSnakeRect.size());
    }
    else if(nScore>30){
        painter.setPen(Qt::black);
        painter.setBrush(Qt::white);
        painter.drawRects(&vSnakeRect[0],vSnakeRect.size());
    }

    //画食物
    painter.setPen(Qt::black);
    painter.setBrush(Qt::green);
    painter.drawRect(food);

    //画炸弹
    painter.setPen(Qt::black);
    painter.setBrush(Qt::blue);
    painter.drawRects(&boom[0],boom.size());

    if(Shorten){
        vSnakeRect.pop_back();
        Shorten=false;
    }

    if(Over){//游戏结束，停止计时器
        timer->stop();
        IsClose();
        nScore=0;
    }

}

//初始化蛇
void Snake5::initSnake(){
    Run=true;
    Over=false;
    Direction=2;//默认向下

    food=CreateRect();

    vSnakeRect.resize(5);//初始化蛇的长度
    //利用一个for循环初始化vector
    for(int i=0;i<vSnakeRect.size();i++){
        QRect rect(100,70+10*i,10,10);//生成小方块
        vSnakeRect[vSnakeRect.size()-1-i]=rect;//小方块赋值到容器
    }
    vSnakeHead=vSnakeRect.first();//指定蛇头位置
    timer=new QTimer(this);//设定计时器
    timer->start(speed);//设定时间
    connect(timer,SIGNAL(timeout()),SLOT(Snake_update()));//信号和槽
}

void Snake5::initBoom(){
    boom.resize(nScore+1);
    for(int i=0;i<boom.size();i++){
        int x,y;
        x=qrand()%42;
        y=qrand()%52;
        QRect rect(40+x*10,40+y*10,10,10);
        boom[boom.size()-1-i]=rect;
    }
}

//移动
void Snake5::Snake_update(){
    vSnakeHead=vSnakeRect.first();//获取到蛇头
    IsEat();
    IsHit();
    IsBoom();
    IsLose();
    if(nScore==-1){
        IsClose();
        nScore=0;
    }
    //让数组移动，除了蛇头，后面的到前面的位置
    for(int j=0;j<vSnakeRect.size()-1;j++){
        vSnakeRect[vSnakeRect.size()-1-j]=vSnakeRect[vSnakeRect.size()-2-j];
    }
    //根据方向对蛇头小方块的移动方向进行调整
    switch (Direction) {
    case 1:
        vSnakeHead.setTop(vSnakeHead.top()-10);
        vSnakeHead.setBottom(vSnakeHead.bottom()-10);
        break;
    case 2:
        vSnakeHead.setBottom(vSnakeHead.bottom()+10);
        vSnakeHead.setTop(vSnakeHead.top()+10);
        break;
    case 3:
        vSnakeHead.setLeft(vSnakeHead.left()-10);
        vSnakeHead.setRight(vSnakeHead.right()-10);
        break;
    case 4:
        vSnakeHead.setLeft(vSnakeHead.left()+10);
        vSnakeHead.setRight(vSnakeHead.right()+10);
        break;
    default:
        break;
    }
    vSnakeRect[0]=vSnakeHead;//第一个节点设置为蛇头位置
    if(vSnakeHead.left()<40||vSnakeHead.right()>460||vSnakeHead.top()<40||vSnakeHead.bottom()>560){
        nScore=-1;
        Over=true;
    }
    update();//paintEvent更新
}
void Snake5::keyPressEvent(QKeyEvent *event){
    QKeyEvent *key=(QKeyEvent*)event;
    switch(key->key()){
        case Qt::Key_Up:Direction=1;
        break;
    case Qt::Key_Down:Direction=2;
        break;
    case Qt::Key_Left:Direction=3;
        break;
    case Qt::Key_Right:Direction=4;
        break;
    default:;
    }
}

QRect Snake5::CreateRect(){
    int x,y;
    x=qrand()%42;
    y=qrand()%52;
    QRect rect(40+x*10,40+y*10,10,10);
    return rect;
}


void Snake5::IsEat(){
    if(vSnakeHead==food){//如果蛇头和食物重合，说明已经吃到食物
        nScore+=1;
        Change=true;
        vSnakeHead=food;
        vSnakeRect.push_back(vSnakeRect.last());//加入节点让蛇身变长
        food=CreateRect();//吃到食物后再生成一个食物
        if(speed>50){
            speed-=10;
            timer->stop();//停止当前计时器
            timer->start(speed);//设置新的计时器
        }
    }
}
void Snake5::IsHit(){
    for(int i=1;i<vSnakeRect.size();i++){
        if(vSnakeHead==vSnakeRect[i]){
            nScore=-1;
            Over=true;
            update();
        }
    }
}

void Snake5::IsBoom(){
    for(int i=0;i<boom.size();i++){
        if(vSnakeHead==boom[i]){
            Shorten=true;
            nScore-=1;
            if(nScore>=0){
                initBoom();
            }
        }
    }
}

void Snake5::IsLose(){
    if(nScore<0){
        Over=true;
        update();
    }
}

void Snake5::IsClose(){
    if(nScore<0){
        this->close();
        D=new Dialog_1();
        D->show();
    }
}
